# -*- coding: utf-8 -*-
"""
Created on Thu May 15 14:17:19 2025

@author: tianr
"""
import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
import time
from mlxtend.preprocessing import TransactionEncoder
from mlxtend.frequent_patterns import apriori, fpgrowth, association_rules
import psutil
from statsmodels.tsa.seasonal import seasonal_decompose

# 添加中文字体设置
plt.rcParams['font.sans-serif'] = ['Microsoft YaHei']  # 设置微软雅黑字体
plt.rcParams['axes.unicode_minus'] = False  # 解决负号显示问题

# 定义商品类别映射
category_mapping = {
    '智能手机': '电子产品', '笔记本电脑': '电子产品', '平板电脑': '电子产品',
    '智能手表': '电子产品', '耳机': '电子产品', '音响': '电子产品',
    '相机': '电子产品', '摄像机': '电子产品', '游戏机': '电子产品',
    '上衣': '服装', '裤子': '服装', '裙子': '服装', '内衣': '服装',
    '鞋子': '服装', '帽子': '服装', '手套': '服装', '围巾': '服装',
    '外套': '服装', '零食': '食品', '饮料': '食品', '调味品': '食品',
    '米面': '食品', '水产': '食品', '肉类': '食品', '蛋奶': '食品',
    '水果': '食品', '蔬菜': '食品', '家具': '家居', '床上用品': '家居',
    '厨具': '家居', '卫浴用品': '家居', '文具': '办公', '办公用品': '办公',
    '健身器材': '运动户外', '户外装备': '运动户外', '玩具': '玩具',
    '模型': '玩具', '益智玩具': '玩具', '婴儿用品': '母婴',
    '儿童课外读物': '母婴', '车载电子': '汽车用品', '汽车装饰': '汽车用品'
}


def get_memory_usage():
    """获取当前内存使用情况（GB）"""
    process = psutil.Process()
    return process.memory_info().rss / 1e9


purchased_history = pd.read_csv('D:/DTR/MyWork/2025/DataMining/personalProject/output/items_10G_one.csv')
product = pd.read_csv('D:/DTR/MyWork/2025/DataMining/personalProject/output/product.csv')

# 记录内存使用
memory_usage = []
times = []
start_time = time.time()
memory_usage.append(get_memory_usage())
times.append(time.time() - start_time)
print(f"数据读取完成，内存使用: {memory_usage[-1]:.2f} GB")

# 处理items列（将字符串转换为列表）
print("处理数据中...")
purchased_history['items'] = purchased_history['items'].apply(lambda x: eval(x))

# 1. 准备数据
# 合并purchased_history和product，获取每个订单中商品的类别和价格信息
merged_product = purchased_history.explode('items').merge(product, left_on='items', right_on='id', how='left')


# 将商品类别进行映射
merged_product['category'] = merged_product['category'].map(category_mapping)


# 1.1. 数据预处理：转换日期格式并提取时间特征
merged_product['purchase_date'] = pd.to_datetime(merged_product['purchase_date'])
merged_product['quarter'] = merged_product['purchase_date'].dt.quarter
merged_product['month'] = merged_product['purchase_date'].dt.month
merged_product['day_of_week'] = merged_product['purchase_date'].dt.day_name()

# 2. 季节性模式分析：按月份、星期统计商品类别购买频率
monthly_category_counts = merged_product.groupby(['month', 'category'])['items'].count().unstack(fill_value=0)
dayofweek_category_counts = merged_product.groupby(['day_of_week', 'category'])['items'].count().unstack(fill_value=0)

# 选择前5个最受欢迎的类别进行季节性分析
top_categories = merged_product['category'].value_counts().head(5).index
#monthly_top_categories = monthly_category_counts[top_categories]
monthly_top_categories=monthly_category_counts

# 绘制季节性趋势图（购买次数与月份的关系）
plt.figure(figsize=(14, 7))
for category in merged_product['category'].value_counts().index:
    plt.plot(monthly_category_counts.index, monthly_category_counts[category], marker='o', label=category)
plt.title('月度商品类别购买频率变化')
plt.xlabel('月份')
plt.ylabel('购买次数')
plt.xticks(range(1, 13))
plt.legend()
plt.grid(True)
plt.show()

# 3. 特定商品类别购买频率的时间变化
# 以电子产品为例，分析其在各季度的购买频率
electronics_trend = merged_product[merged_product['category'] == '服装'].groupby('quarter')['items'].count()

print(electronics_trend)

plt.figure(figsize=(10, 5))
electronics_trend.plot(kind='bar', color='skyblue')
plt.title('服装季度购买频率')
plt.xlabel('季度')
plt.ylabel('购买次数')
plt.xticks(rotation=0)
plt.show()

# 4. 时序关联规则挖掘："先购买A，后购买B"模式
# 按用户和日期排序，构建时序事务
time_sorted_data = merged_product.sort_values(['purchase_date'])
user_sessions = time_sorted_data.groupby('purchase_date').agg({
    'category': list,
    'items': list
}).reset_index()

print(user_sessions)
# 构建时序事务（相邻时间点的事务）
sequential_transactions = []
for i in range(len(user_sessions) - 1):
    current_cats = set(user_sessions.iloc[i]['category'])
    next_cats = set(user_sessions.iloc[i+1]['category'])
    sequential_transactions.append((current_cats, next_cats))

# 计算时序关联规则（简化版：统计A出现后B出现的频率）
def calculate_sequential_rules(transactions, min_support=0.01, min_confidence=0.6):
    rule_counts = {}
    antecedent_counts = {}
    
    for current, next in transactions:
        for a in current:
            antecedent_counts[a] = antecedent_counts.get(a, 0) + 1
            for b in next:
                if a != b:
                    rule_counts[(a, b)] = rule_counts.get((a, b), 0) + 1
    
    # 筛选符合条件的规则
    valid_rules = []
    for (a, b), count in rule_counts.items():
        support = count / len(transactions)
        confidence = count / antecedent_counts[a]
        if support >= min_support and confidence >= min_confidence:
            valid_rules.append({
                'antecedent': a,
                'consequent': b,
                'support': support,
                'confidence': confidence,
                'lift': confidence / (antecedent_counts[b] / len(transactions))
            })
    
    return pd.DataFrame(valid_rules).sort_values('confidence', ascending=False)

# 计算时序关联规则
sequential_rules = calculate_sequential_rules(sequential_transactions, min_support=0.01, min_confidence=0.6)

print('\n季节性购买模式分析：')
print(monthly_top_categories)

print('\n电子产品季度购买频率：')
print(electronics_trend)

print('\n时序关联规则（先购买A，后购买B）：')
if not sequential_rules.empty:
    print(sequential_rules[['antecedent', 'consequent', 'support', 'confidence', 'lift']])
else:
    print("未发现满足条件的时序关联规则")
    